package com.bensonbasement.snorflux.server.world;

import java.util.LinkedList;
import java.util.List;

import com.bensonbasement.snorflux.memory.SpaceInfo;
import com.bensonbasement.snorflux.server.world.prototypes.SpacePrototype;
import com.bensonbasement.snorflux.utils.Coords;
import com.bensonbasement.snorflux.utils.Direction;
import com.bensonbasement.snorflux.utils.SpaceReference;

public class Space extends WorldElement implements ISmallEntityHolder, IBigEntityHolder {
	
	private final InventoryHelper inventoryHelper = new InventoryHelper();
	private BigEntity bigEntity = null;
	private final Level level;
	private final Coords coords;
	
	public Space(World world, SpacePrototype prototype, Level level, Coords coords) {
		super(world, prototype);
		this.level = level;
		this.coords = coords;
	}
	
	
	@Override
	public void setBigEntity(BigEntity entity) {
		if (entity != null && this.bigEntity != null && entity != this.bigEntity) {
			throw new RuntimeException("Trying to add bigEntity to already-occupied space!");
		}
		this.bigEntity = entity;
	}

	@Override
	public BigEntity getBigEntity() {
		return this.bigEntity;
	}

	@Override
	public void addSmallEntity(SmallEntity entity) {
		inventoryHelper.addSmallEntity(entity);
	}

	@Override
	public void removeSmallEntity(SmallEntity entity) {
		inventoryHelper.removeSmallEntity(entity);
	}

	@Override
	public List<SmallEntity> getSmallEntities() {
		return inventoryHelper.getSmallEntities();
	}
	
	@Override
	public Level getLevel() {
		return this.level;
	}

	public Coords getCoords() {
		return coords;
	}
	
	public int getX() {
		return this.coords.getX();
	}
	
	public int getY() {
		return this.coords.getY();
	}
	
	@Override
	public Space getSpace() {
		return this;
	}
	
	public SpaceReference getReference() {
		return new SpaceReference(coords,level.getLevelNum());
	}
	
	public Space getNeighbor(Direction direction) {
		Coords neighborCoords = this.coords.getNeighbor(direction);
		return this.level.getSpace(neighborCoords);
	}
	
	@Override
	public SpaceInfo render(IViewer viewer) {
		// TODO: Update this when the Jython attribute stuff is created.
		if (viewer.canSeeInLocation(this)) {
			SpaceInfo retVal = new SpaceInfo(this.getWorldElementID(),this.getGlyph(),this.getName(),this.coords,this.level.getLevelNum());
			return retVal;
		}
		else {
			return null;
		}
	}
	
	@Override
	public List<WorldElement> getAllWorldElements() {
		LinkedList<WorldElement> retVal = new LinkedList<WorldElement>();
		retVal.add(this);
		if (this.bigEntity != null) {
			retVal.addAll(this.bigEntity.getAllWorldElements());
		}
		for (SmallEntity entity : this.inventoryHelper.getSmallEntities()) {
			retVal.addAll(entity.getAllWorldElements());
		}
		return retVal;
	}
}
